package com.ziyun.erp.modules.capital.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.pay.api.PayMoneyService;
import com.pay.api.RecallService;
import com.pay.constant.PayResult;
import com.pay.model.PayRecallResult;
import com.pay.model.payMoney.PayOrderParam;
import com.pay.model.payMoney.PayOrderResult;
import com.pay.model.payMoney.QueryOrderParam;
import com.service.common.protocol.ResultCode;
import com.utility.DateUtils;
import com.ziyun.erp.common.e.capital.ApplyStatusEnum;
import com.ziyun.erp.common.utils.ChineseCalendarUtils;
import com.ziyun.erp.modules.capital.dao.MerchantApplyCashDao;
import com.ziyun.erp.modules.capital.entity.*;
import com.ziyun.erp.modules.capital.service.*;
import com.ziyun.erp.modules.order.service.ErpOrderService;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.common.utils.R;
import io.renren.modules.sys.service.MailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("merchantApplyCashService")
public class MerchantApplyCashServiceImpl extends ServiceImpl<MerchantApplyCashDao, MerchantApplyCashEntity> implements MerchantApplyCashService {

    @Autowired
    private MerchantApplyCashItemsService merchantApplyCashItemsService;

    @Autowired
    private RemittanceMerchantsService remittanceMerchantsService;

    @Autowired
    private MerchantApplyLogService merchantApplyLogService;

    @Autowired
    private MerchantFlowService merchantFlowService;

    @Autowired
    private MerchantPurseService merchantPurseService;

    @Autowired
    private PayMoneyService payMoneyService;

    @Autowired
    private RecallService recallService;

    @Autowired
    private MerchantOrderAccountService merchantOrderAccountService;

    @Autowired
    private ErpOrderService erpOrderService;

    @Autowired
    private MailService mailService;

    private static Logger logger = LoggerFactory.getLogger(MerchantApplyCashServiceImpl.class);

    //申请提现地址
    @Value("${umf.applyAddress}")
    private String applyAddress;
    // 申请提现回调地址
    @Value("${umf.applyNotifyAddress}")
    private String applyNotifyAddress;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        Page<MerchantApplyCashEntity> page = new Query<MerchantApplyCashEntity>(params).getPage();

        page.setRecords(this.baseMapper.selectApplyCashPage(page, params));

        return new PageUtils(page);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String applyCashCheck(String userName, Integer id) {
        Date currentDate = new Date();
        //先查询该申请单状态
        MerchantApplyCashEntity merchantApplyCash = this.selectById(id);

        //判断状态
        if (!(merchantApplyCash.getApplyStatus().intValue() == 0)) {
            throw new RRException("该提现单状态异常,请刷新后重试!");
        }

        // 校验订单明细状态
        List<MerchantApplyCashItemsEntity> merchantApplyCashItemsEntityList =
                this.merchantApplyCashItemsService.selectList(new EntityWrapper<MerchantApplyCashItemsEntity>()
                        .eq("apply_cash_id", id));
        for (MerchantApplyCashItemsEntity merchantApplyCashItems : merchantApplyCashItemsEntityList){
            if (!merchantApplyCashItems.getOrderStatus().equals("finish")){
                throw new RRException("订单状态异常,请联系管理员!");
            }
        }

        // 查询小b 是否配置银行卡相关信息
        RemittanceMerchantsEntity remittanceMerchants = this.remittanceMerchantsService.selectOne(
                new EntityWrapper<RemittanceMerchantsEntity>()
                        .eq("seller_id", merchantApplyCash.getSellerId())
                        .eq("merchant_type", merchantApplyCash.getMerchantType()));
        if (remittanceMerchants == null) {
            throw new RRException("未查询到该商户银行卡信息!");
        }


        // 计算汇费
        BigDecimal totalFee = BigDecimal.ZERO;
        String purpose = "工厂申请提现";
        if (merchantApplyCash.getMerchantType().intValue() == 0) { // 小b 提现 需要计算汇费
            totalFee = this.computeFee(id,merchantApplyCash.getApplyMoney(), currentDate);
            purpose = "小b申请提现";
        }

        //生成请求联动data
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        String orderDate = format.format(currentDate);
        PayOrderParam payOrderParam = this.setApplyData(
                merchantApplyCash.getApplyMoney().subtract(totalFee),
                purpose,
                orderDate, remittanceMerchants);

        // 调用支付 微服务jar
        PayResult<PayOrderResult> payResult = this.payMoneyService.payOrder(payOrderParam);

        PayOrderResult payOrderResult = payResult.getData();

        //处理返回值 此处微服务支付中心已经处理过返回结果 这里只有三种情况
        // 1. 打款成功 2. 打款中  3.打款失败
        MerchantApplyLogEntity merchantApplyLogEntity = new MerchantApplyLogEntity();
        merchantApplyLogEntity.setApplyCashId(id);
        merchantApplyLogEntity.setApplyPayId(payOrderParam.getOrder_id());
        merchantApplyLogEntity.setBankNo(payOrderParam.getRecv_account());
        merchantApplyLogEntity.setBank(payOrderParam.getBank_brhname());
        merchantApplyLogEntity.setBankOwner(payOrderParam.getRecv_user_name());

        if (payResult.getCode() == ResultCode.PAYMENT_SUCCESS.getCode()) {// 打款成功
            // 只有 实时打款才会有该状态 状态变更与打款中保持一致 通过异步接口更改状态

            //将单据状态更改为操作中
            MerchantApplyCashEntity condition = new MerchantApplyCashEntity();
            condition.setId(id);
            condition.setApplyStatus(1);
            condition.setAuditor(userName);
            condition.setAuditTime(currentDate);
            this.updateById(condition);

            merchantApplyLogEntity.setApplyLogStatus(0);
            merchantApplyLogEntity.setPayNo(payOrderResult.getTrade_no());
            merchantApplyLogEntity.setMessage(payOrderResult.getRet_code() + ";" + payOrderResult.getRet_msg());
            merchantApplyLogEntity.setCreateTime(new Date());
            merchantApplyLogEntity.setRemark("订单打款成功");
            this.merchantApplyLogService.insertWithPRN(merchantApplyLogEntity);

            //回写主表支付id 与联动体现单号
            MerchantApplyCashEntity merchantApplyCashTemp = new MerchantApplyCashEntity();
            merchantApplyCashTemp.setId(merchantApplyCash.getId());
            merchantApplyCashTemp.setPayNo(payOrderResult.getTrade_no());
            merchantApplyCashTemp.setApplyPayId(payOrderParam.getOrder_id());
            this.updateById(merchantApplyCashTemp);

            //写入资金流水表
            MerchantFlowEntity merchantFlow = new MerchantFlowEntity();
            merchantFlow.setSellerId(merchantApplyCash.getSellerId());
            merchantFlow.setMerchantType(merchantApplyCash.getMerchantType());
            merchantFlow.setFlowType(1);
            merchantFlow.setSourceType(0);
            merchantFlow.setFlowMoney(BigDecimal.valueOf(payOrderParam.getAmount()));
            merchantFlow.setSourceOrder(merchantApplyCash.getId().toString());
            merchantFlow.setCreateDate(new Date());
            this.merchantFlowService.insert(merchantFlow);
        }
        if (payResult.getCode() == ResultCode.PAYMENT_MIDDLE.getCode()) { //打款中
            // 此处可能直接返回打款成功,也可能是中间状态 如 00200014  00180021
            // 全部作为打款中 记录编码 等待异步通知

            //将单据状态更改为操作中
            MerchantApplyCashEntity condition = new MerchantApplyCashEntity();
            condition.setId(id);
            condition.setApplyStatus(1);
            condition.setAuditor(userName);
            condition.setAuditTime(currentDate);
            this.updateById(condition);

            merchantApplyLogEntity.setApplyLogStatus(0);
            merchantApplyLogEntity.setPayNo(payOrderResult.getTrade_no());
            merchantApplyLogEntity.setMessage(payOrderResult.getRet_code() + ";" + payOrderResult.getRet_msg());
            merchantApplyLogEntity.setCreateTime(new Date());
            merchantApplyLogEntity.setRemark("订单打款中");
            this.merchantApplyLogService.insertWithPRN(merchantApplyLogEntity);

            //回写主表支付id 与联动体现单号
            MerchantApplyCashEntity merchantApplyCashTemp = new MerchantApplyCashEntity();
            merchantApplyCashTemp.setId(merchantApplyCash.getId());
            merchantApplyCashTemp.setPayNo(payOrderResult.getTrade_no());
            merchantApplyCashTemp.setApplyPayId(payOrderParam.getOrder_id());
            this.updateById(merchantApplyCashTemp);

            //写入资金流水表
            MerchantFlowEntity merchantFlow = new MerchantFlowEntity();
            merchantFlow.setSellerId(merchantApplyCash.getSellerId());
            merchantFlow.setMerchantType(merchantApplyCash.getMerchantType());
            merchantFlow.setFlowType(1);
            merchantFlow.setSourceType(0);
            merchantFlow.setFlowMoney(BigDecimal.valueOf(payOrderParam.getAmount()));
            merchantFlow.setSourceOrder(merchantApplyCash.getId().toString());
            merchantFlow.setCreateDate(new Date());
            this.merchantFlowService.insert(merchantFlow);


        }
        if (payResult.getCode() == ResultCode.PAYMENT_ERROR.getCode()) { //打款失败
            merchantApplyLogEntity.setApplyLogStatus(1);
            merchantApplyLogEntity.setPayNo(payOrderResult.getTrade_no());
            merchantApplyLogEntity.setMessage(payOrderResult.getRet_code() + ";" + payOrderResult.getRet_msg());
            merchantApplyLogEntity.setCreateTime(new Date());
            merchantApplyLogEntity.setRemark("订单打款失败");
            this.merchantApplyLogService.insertWithPRN(merchantApplyLogEntity);

        }

        if (payOrderResult != null) {
            return payOrderResult.getRet_msg();
        } else {
            return payResult.getMessage();
        }

    }

    /**
     * 处理回调信息
     *
     * @param map
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String getNotifyInfo(Map<String, Object> map) {
        String params = map.get("params") + "";
        logger.info("回调参数:" + params);
        //  调用回调 微服务jar
        try {
            PayResult<PayRecallResult> payResult = this.recallService.payRecall(params);

            PayRecallResult payRecallResult = payResult.getData();

            String ret_code = payRecallResult.getRet_code();
            //联动体现单号
            String trade_no = payRecallResult.getTrade_no();
            // 紫云体现单号
            String order_id = payRecallResult.getOrder_id();

            // 根据以上单号 查询提现主表信息
            MerchantApplyCashEntity merchantApplyCash = this.selectOne(new EntityWrapper<MerchantApplyCashEntity>()
                    .eq("pay_no", trade_no)
                    .eq("apply_pay_id", order_id));

            if (merchantApplyCash == null) {
                throw new RRException("未查询到相关体现信息");
            }
            RemittanceMerchantsEntity remittanceMerchants = this.remittanceMerchantsService.selectOne(
                    new EntityWrapper<RemittanceMerchantsEntity>()
                            .eq("seller_id", merchantApplyCash.getSellerId())
                            .eq("merchant_type", merchantApplyCash.getMerchantType()));
            MerchantApplyLogEntity log = new MerchantApplyLogEntity();
            log.setApplyCashId(merchantApplyCash.getId());
            log.setApplyPayId(order_id);
            log.setBank(remittanceMerchants.getReceiverAccountBranch());
            log.setBankNo(remittanceMerchants.getReceiverAccount());
            log.setBankOwner(remittanceMerchants.getReceiverName());
            log.setMobile(remittanceMerchants.getReceiverMobile());

            // 先判断 ret_code 状态
            if (ret_code.equals("0000")) { // 请求成功
                //交易状态
                String tradeState = payRecallResult.getTrade_state();
                if (tradeState.equals("4")) { // 单据支付成功
                    // 更新 申请体现信息为打款成功
                    MerchantApplyCashEntity merchantApplyCashTemp = new MerchantApplyCashEntity();
                    merchantApplyCashTemp.setId(merchantApplyCash.getId());
                    merchantApplyCashTemp.setActualTime(new Date());
                    merchantApplyCashTemp.setApplyStatus(ApplyStatusEnum.GIVING_SUCCESS.toInt());
                    this.updateById(merchantApplyCashTemp);

                    //更新原订单信息为打款成功
                    this.merchantOrderAccountService.updateByCashId(merchantApplyCash.getId());


                    //更改资金表 打款后金额
                    MerchantPurseEntity merchantPurse = new MerchantPurseEntity();
                    merchantPurse.setMerchantType(merchantApplyCash.getMerchantType());
                    merchantPurse.setSellerId(merchantApplyCash.getSellerId());
                    merchantPurse.setCashAmountPresent(merchantApplyCash.getApplyMoney());
                    this.merchantPurseService.updatePurseAfter(merchantPurse);


                    if (merchantApplyCash.getMerchantType().equals("1")) { // 工厂提现需要更改appBillId 状态
                        //todo  待定怎么做
                    }
                    log.setPayNo(payRecallResult.getTrade_no());
                    log.setApplyLogStatus(2);
                    log.setMessage(payRecallResult.getRet_code() + ":" + payRecallResult.getRet_msg());
                    log.setCreateTime(new Date());
                    log.setRemark("订单支付成功!");
                    this.merchantApplyLogService.insertWithPRN(log);

                    //商户提现，生产单付款状态回写
                    List<String> allotOrderList = new ArrayList<>();
                    try {
                        List<MerchantOrderAccountEntity> merchantOrderAccountList = this.merchantOrderAccountService.selectListByCashId(merchantApplyCash.getId());
                        for (MerchantOrderAccountEntity temp : merchantOrderAccountList) {
                            allotOrderList.add(temp.getOrderId().toString());
                        }
                        erpOrderService.sellerCashBack(allotOrderList);
                    } catch (Exception e) {
                        // 失败不处理
                        try {
                            mailService.sendSysErrorMail(merchantApplyCash.getId()+ "支付回调 处理生产单付款状态回写 异常!" + allotOrderList +  "错误信息:" + e.getMessage());
                        } catch (Exception e1) {

                        }
                    }

                    return payRecallResult.getResMetaData();

                } else { //单据支付失败
                    // 更新 申请体现信息为打款失败
                    MerchantApplyCashEntity merchantApplyCashTemp = new MerchantApplyCashEntity();
                    merchantApplyCashTemp.setId(merchantApplyCash.getId());
                    merchantApplyCashTemp.setApplyStatus(ApplyStatusEnum.GIVING_CALLBACK_FAIL.toInt());
                    this.updateById(merchantApplyCashTemp);

                    //将流水表记录置位删除
                    MerchantFlowEntity merchantFlow = new MerchantFlowEntity();
                    merchantFlow.setDelFlag(1);
                    this.merchantFlowService.update(merchantFlow, new EntityWrapper<MerchantFlowEntity>()
                            .eq("seller_id", merchantApplyCash.getSellerId())
                            .eq("merchant_type", merchantApplyCash.getMerchantType())
                            .eq("source_type", 0)
                            .eq("source_order", merchantApplyCash.getId())
                    );

                    //记录失败日志
                    log.setPayNo(trade_no);
                    log.setApplyLogStatus(1);
                    log.setMessage(payRecallResult.getRet_code() + ":" + payRecallResult.getRet_msg());
                    log.setCreateTime(new Date());
                    log.setRemark("订单支付回调通知失败!");
                    this.merchantApplyLogService.insertWithPRN(log);
                }

                return payRecallResult.getResMetaData();

            } else if (ret_code.equals("00200014")) { // 状态未明
                log.setPayNo(trade_no);
                log.setApplyLogStatus(1);
                log.setMessage(payRecallResult.getRet_code() + ":" + payRecallResult.getRet_msg());
                log.setCreateTime(new Date());
                log.setRemark("订单支付结果不明确");
                this.merchantApplyLogService.insertWithPRN(log);

                return null;
            }
        } catch (Exception e) {
            logger.error("处理返回数据异常" + e.getMessage(),e);
            //e.printStackTrace();
            return null;
        }
        return null;

    }

    /**
     * 查询联动订单状态
     * @param queryParams
     * @return
     */
    @Override
    public PayResult<PayOrderResult> searchUmfOrderStatus(Map<String, Object> queryParams) {
        QueryOrderParam queryOrderParam = new QueryOrderParam();
        queryOrderParam.setMer_id("50956");
        queryOrderParam.setOrder_id(queryParams.get("orderId").toString());
        String merDate = queryParams.get("merDate").toString();
        queryOrderParam.setMer_date(DateUtils.getStrToDate(merDate));
        PayResult<PayOrderResult>  payResult = this.payMoneyService.queryPayStatus(queryOrderParam);
        return payResult;
    }

    /**
     * 确认已打款
     * @param queryParams
     * @return
     */
    @Override
    @Transactional
    public void confirmCash(Map<String, Object> queryParams) {
        // 1. 先查询 applyStatus
        Integer cashId = Integer.parseInt(queryParams.get("id").toString());
        MerchantApplyCashEntity merchantApplyCash =  this.baseMapper.selectById(cashId);
        if (merchantApplyCash.getApplyStatus().intValue() != 1){
            throw new RRException("当前订单审核状态不是审核中, 不允许确认已打款!");
        }
        // 2.查询联动支付状态
        PayResult<PayOrderResult> payResult = this.searchUmfOrderStatus(queryParams);
        if (payResult.getCode() != ResultCode.PAYMENT_SUCCESS.getCode()){
            throw new RRException("当前订单打款状态不是成功,不允许确认已打款!");
        }

        //3.确认打款操作
        // 更新 申请体现信息为打款成功
        MerchantApplyCashEntity merchantApplyCashTemp = new MerchantApplyCashEntity();
        merchantApplyCashTemp.setId(merchantApplyCash.getId());
        merchantApplyCashTemp.setActualTime(new Date());
        merchantApplyCashTemp.setApplyStatus(ApplyStatusEnum.GIVING_SUCCESS.toInt());
        this.updateById(merchantApplyCashTemp);
        //更新原订单信息为打款成功
        int i= this.merchantOrderAccountService.updateByCashId(merchantApplyCash.getId());
        if(i ==0){
            throw new RRException("更新订单状态为打款成功异常,请联系管理员检查数据!");
        }
        // 模拟插入日志
        MerchantApplyLogEntity log = new MerchantApplyLogEntity();
        log.setApplyCashId(merchantApplyCash.getId());
        log.setApplyPayId(merchantApplyCash.getApplyPayId());
        log.setPayNo(merchantApplyCash.getPayNo());
        log.setApplyLogStatus(2);
        log.setMessage("交易成功");
        log.setCreateTime(new Date());
        log.setRemark("手动确认打款操作");
        this.merchantApplyLogService.insert(log);

    }

    /**
     * 重置打款状态
     * @param queryParams
     */
    @Override
    @Transactional
    public void resetApplyStatus(Map<String, Object> queryParams) {
        // 1. 先查询 applyStatus
        Integer cashId = Integer.parseInt(queryParams.get("id").toString());
        MerchantApplyCashEntity merchantApplyCash =  this.baseMapper.selectById(cashId);
        if (merchantApplyCash.getApplyStatus().intValue() != 4){
            throw new RRException("当前订单申请状态不是失败, 不允许重置审核状态!");
        }

        // 2.查询联动支付状态
        PayResult<PayOrderResult> payResult = this.searchUmfOrderStatus(queryParams);
        if (payResult.getCode() != ResultCode.PAYMENT_ERROR.getCode()){
            throw new RRException("当前订单打款状态不是失败, 不允许重置审核状态!");
        }

        // 3. 重置审核状态为待审核
        MerchantApplyCashEntity condition = new MerchantApplyCashEntity();
        condition.setId(cashId);
        condition.setApplyStatus(0);
        this.updateById(condition);

    }


    @Override
    public MerchantApplyCashEntity selectApplyCashById(Integer id) {
        return this.baseMapper.selectApplyCashById(id);
    }


    /**
     * 计算提现单设计汇费 非实时接口
     *
     * @param id
     * @param currentDate
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public BigDecimal computeFee(Integer id, BigDecimal applyMoney, Date currentDate) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        // 首先计算预估到账天数
        int dayOfNumber = 0;
        // 1.计算当前日期是否为工作日
        if (ChineseCalendarUtils.isWorkDay(currentDate)) { // 是工作日

            // 判断是否大于16:30
            if (!ChineseCalendarUtils.compareHourMinute(currentDate, "16:30:00")) {
                // 大于 则计算 距离当前日期第二天的 天数
                dayOfNumber = ChineseCalendarUtils.getNextWorkDays(currentDate);

            } else { // 小于 则是当天到账
                dayOfNumber = 0;
            }
        } else {
            // 非工作日 则计算下一个工作日 日距离当前天数
            dayOfNumber = ChineseCalendarUtils.getNextWorkDays(currentDate);
        }

        //计算出预计到账日期
        Date expectDate = ChineseCalendarUtils.addDate(currentDate, dayOfNumber);

        // 循环订单明细 计算汇费
        List<MerchantApplyCashItemsEntity> merchantApplyCashItemsEntityList =
                this.merchantApplyCashItemsService.selectList(new EntityWrapper<MerchantApplyCashItemsEntity>()
                        .eq("apply_cash_id", id));

        if (CollectionUtils.isEmpty(merchantApplyCashItemsEntityList)) {
            throw new RRException("提现单明细异常!");
        }

        BigDecimal totalFee = BigDecimal.ZERO;
        BigDecimal totalMoney = BigDecimal.ZERO;
        List<MerchantApplyCashItemsEntity> updateItemList = new ArrayList<>();
        /*
         * 奖励金政策发生变化， 提现规则响应变化
         * 1.2018.11.16: 23:59:59  之前的订单 按照 商品总额+运费+随机立减 计算提现金额
         * 2.2018.11.16: 23:59:59  之后的订单 按照 商品总额+运费 计算提现金额
         * 3.一次申请提现 下单日期不能夸 2018.11.16 天
         */
        List<Integer> gtDay = new ArrayList<>(); //大于指定日期订单数
        List<Integer> eltDay = new ArrayList<>(); // 小于等于指定日期订单数
        for (MerchantApplyCashItemsEntity merchantApplyCash : merchantApplyCashItemsEntityList) {

            // 取出订单完成日期
            Date finishTime = merchantApplyCash.getFinishTime();

            // 比较预计到账日期与订单完成日期 时间差 计算汇费
            int differenceDay = ChineseCalendarUtils.getDifferenceDays(expectDate, finishTime);

            //计算汇率
            double percentage = this.getPercentage(differenceDay);

            if (percentage == -1) {
                throw new RRException("订单日期异常,请联系管理员!");
            }

            // 判断日期 与 2018.11.16: 23:59:59 比较
            Date orderCreateTime = merchantApplyCash.getOrderCreateTime();
            Date specifiedTime = io.renren.common.utils.DateUtils.stringToDate("2018-11-16 23:59:59", io.renren.common.utils.DateUtils.DATE_TIME_PATTERN);
            if(orderCreateTime.getTime() > specifiedTime.getTime()){
                gtDay.add(1);
            }else {
                eltDay.add(1);
            }
            if(gtDay.size()>0 && eltDay.size()>0){
                throw new RRException("订单:"+ merchantApplyCash.getOrderAccountId()+"在2018年11月16日,提现规则发生变化,该数据异常,请联系管理员!");
            }

            // 商品总金额
            BigDecimal goodsTotalAmount = merchantApplyCash.getTotalAmount();
            // 运费
            BigDecimal costFreight = merchantApplyCash.getCostFreight();
            // 随机立减
            BigDecimal pmtRandom = merchantApplyCash.getPmtRandom();

            BigDecimal discount = merchantApplyCash.getDiscount();

            BigDecimal putForwardAmount = BigDecimal.ZERO;
            if (eltDay.size() >0 && merchantApplyCash.getIsAllot() == 0){ // 老提现规则
                logger.info("老提现规则!");
                // 提现金额
                putForwardAmount = goodsTotalAmount.add(costFreight).add(pmtRandom);
                totalMoney = totalMoney.add(putForwardAmount);
            }

            if(gtDay.size() >0 && merchantApplyCash.getIsAllot() == 0){ // 新提现规则
                logger.info("新提现规则!");
                // 提现金额
                putForwardAmount = goodsTotalAmount.add(costFreight);
                totalMoney = totalMoney.add(putForwardAmount);
            }

            if (merchantApplyCash.getIsAllot() == 1){ // 分配订单特殊处理
                logger.info("分配订单规则!");
                // 提现金额
                putForwardAmount = goodsTotalAmount.add(costFreight).add(discount);
                totalMoney = totalMoney.add(putForwardAmount);
            }

            // 提现费用
            BigDecimal putForwardFee = BigDecimal.ZERO;
            if (merchantApplyCash.getIsAllot() == 0) { //非分配订单 计算汇费
                putForwardFee = putForwardAmount.multiply(new BigDecimal(percentage));
                putForwardFee = putForwardFee.setScale(3, BigDecimal.ROUND_HALF_DOWN);
            }



            //组装明细提现费用
            MerchantApplyCashItemsEntity itemsUpdate = new MerchantApplyCashItemsEntity();
            itemsUpdate.setId(merchantApplyCash.getId());
            itemsUpdate.setFee(putForwardFee);
            updateItemList.add(itemsUpdate);

            // 提现总费用
            totalFee = totalFee.add(putForwardFee);

        }
        if ( applyMoney.compareTo(totalMoney) !=0){
            throw new RRException("订单明细金额异常,请核对订单!申请金额:"+applyMoney+"明细金额:"+totalMoney);
        }

        //批量更细明细提现费用
        if (updateItemList.size() > 0) {
            this.merchantApplyCashItemsService.updateBatchById(updateItemList);
        }


        // 更新主表 提现总费用 预计到账日期
        MerchantApplyCashEntity merchantApplyCashEntity = new MerchantApplyCashEntity();
        merchantApplyCashEntity.setId(id);
        merchantApplyCashEntity.setApplyFee(totalFee);
        merchantApplyCashEntity.setExpectDate(expectDate);
        this.updateById(merchantApplyCashEntity);

        return totalFee;
    }

    /**
     * 根据天数计算汇费差距
     *
     * @param differenceDay
     * @return
     */
    private double getPercentage(int differenceDay) {
        //todo 平台于2018年8月15日至2019年2月15日期间，减免商户端提前提现手续费！
        double percentage = 0;
        /*switch (differenceDay) {
            case 0:
                percentage = -1;
                break;
            case 1:
                percentage = -1;
                break;
            case 2:
                percentage = 0.007;
                break;
            case 3:
                percentage = 0.006;
                break;
            case 4:
                percentage = 0.005;
                break;
            case 5:
                percentage = 0.004;
                break;
            case 6:
                percentage = 0.003;
                break;
            default:
                percentage = 0;
                break;

        }*/

        return percentage;
    }

    /**
     * 赋值 请求json
     *
     * @param amount  金额
     * @param purpose 秒速
     * @param date    下单日期
     * @param rmer    银行卡相关信息
     * @return
     */
    private PayOrderParam setApplyData(BigDecimal amount, String purpose, String date, RemittanceMerchantsEntity rmer) {

        PayOrderParam payOrderParam = new PayOrderParam();

        payOrderParam.setAmount(amount);//  付款金额 -汇费
        payOrderParam.setBank_brhname(rmer.getReceiverAccountBranch());// 开户行支行全称
        payOrderParam.setBranch_bank_code(rmer.getReceiverAccountNumber());// 支行联行号
        payOrderParam.setCheckFlag("1");// 付款实时和非实时标识 0 实时 1 非实时
        payOrderParam.setProv_name(rmer.getReceiverProvince());// 省
        payOrderParam.setCity_name(rmer.getReceiverCity());// 市
        payOrderParam.setIdentity_code(rmer.getReceiverCredential());// 收款方平台预留证件号码
        payOrderParam.setIdentity_holder(rmer.getReceiverName());// 证件持有人真实姓名
        payOrderParam.setIdentity_type("01");//收款方证件类型 固定身份证
        payOrderParam.setMer_date(date);
        payOrderParam.setMer_id("50956");// 商户号 固定
        payOrderParam.setMobile_no(rmer.getReceiverMobile()); // 收款方手机号
        payOrderParam.setNotify_url(applyNotifyAddress); //服务器异步通知页面路径
        payOrderParam.setOrder_id(this.getPaymentsId());
        payOrderParam.setPurpose(purpose);// 摘要
        payOrderParam.setRecv_account(rmer.getReceiverAccount());// 收款方账号
        payOrderParam.setRecv_account_type("00");//收款方账户类型 00—–银行卡 02—–U付
        payOrderParam.setRecv_bank_acc_pro(rmer.getReceiverBankAccountPro());
        payOrderParam.setRecv_gate_id(rmer.getReceiverGateId());// 收款方账户的发卡行
        payOrderParam.setRecv_user_name(rmer.getReceiverName());// 收款方户名

        return payOrderParam;
    }

    /**
     * TODO 后期考虑单号重复问题
     * 获取支付单号
     *
     * @return
     */
    private static String getPaymentsId() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMddHHmm");
        String payMentsId = "AP-" + dateFormat.format(new Date()) + (int) (Math.random() * 1000000);
        return payMentsId;
    }

}
